﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DmxInterface {

	/// <summary>
	/// Base implementation of Engine functions.
	/// </summary>
	public abstract class BaseEngine : IEngine {

		C5.IDictionary<Device, Universe> _devices = new C5.HashDictionary<Device, Universe>();

		protected C5.IDictionary<Device, Universe> DeviceTable {
			get {
				return _devices;
			}
		}
		
		#region IEngine Members

		public void Register(Device device, Universe universe) {
			if(device == null || universe == null)
				throw new ArgumentNullException();

			if (_devices.Contains(device))
				throw new ArgumentException("The selected device is already registered in this engine.");

			_devices.Add(device, universe);
		}

		public Universe Deregister(Device device) {
			if (device == null)
				throw new ArgumentNullException();

			Universe ret;

			if (_devices.Contains(device)) {
				if (!_devices.Remove(device, out ret)) {
					throw new Exception("Unable to delete the selected device from the engine.");
				}
			}
			else {
				throw new ArgumentException("The selected device has not been registered in this engine.");
			}

			return ret;
		}

		public bool TryDeregister(Device device) {
			if (device == null)
				throw new ArgumentNullException();

			return _devices.Remove(device);
		}

		public IList<Device> Devices {
			get {
				var ret = new C5.ArrayList<Device>(_devices.Count);
				ret.AddAll<Device>(_devices.Keys);
				
				return ret;
			}
		}

		public abstract void Start();

		public abstract void Stop();

		public abstract OperativeFrequency Frequency {
			get;
			set;
		}

		public abstract void Dispose();

		public event EventHandler DataSent;

		protected virtual void OnDataSent() {
			if (DataSent != null)
				DataSent(this, EventArgs.Empty);
		}

		public event EventHandler DataSending;

		protected virtual void OnDataSending() {
			if (DataSending != null)
				DataSending(this, EventArgs.Empty);
		}

		#endregion

	}
}
